import {DynamicTable} from "../element-components/dynamic-table/index.vue.d";
import {TableColumn} from "element-ui/types/table-column";
import {deepClone} from "./index";

// 额外定义的字段，使用symbol进行定义，放在文件内部使用
const otherField = {
  select: Symbol('select'),
  zhixinRadio: Symbol('zhixinRadio')
}

export type ObjectEqualsFun = (a, b) => boolean

export const defaultObjectEquals: ObjectEqualsFun = (a, b) => {
  return a === b
}

export default class elTableUtils {
  /**
   给table赋值，重新遍历新增rowSpan属性，checkRoom，appointmentTime为table里面需要合并的属性名称
   this.table = mergeTableRow(this.table, ['checkRoom', 'appointmentTime'])
   objectSpanMethod({ row, column, rowIndex, columnIndex }) {
     const span = column['property'] + '-span'
     if(row[span]){
         return row[span]
     }
  }
   * table合并行通用
   */
  static mergeTableRow<T>(data: T[], merge: string[]) {
    if (!merge || merge.length === 0) {
      return data
    }
    merge.forEach((m) => {
      const mList = {}
      data = data.map((v, index) => {
        const rowVal = v[m]
        if (mList[rowVal] && mList[rowVal].newIndex === index) {
          mList[rowVal]['num']++
          mList[rowVal]['newIndex']++
          data[mList[rowVal]['index']][m + '-span'].rowspan++
          v[m + '-span'] = {
            rowspan: 0,
            colspan: 0
          }
        } else {
          mList[rowVal] = {num: 1, index: index, newIndex: index + 1}
          v[m + '-span'] = {
            rowspan: 1,
            colspan: 1
          }
        }
        return v
      })
    })
    return data
  }

  static mergeSelect(row) {
  }

  /**
   * selectionChangeWithRowMerge工具
   * @param tableData
   * @param row
   * @param prop
   * @param objectEquals
   * @returns {{findIndex: number, findRow, findRowspan}}
   * @private
   */
  static findRowMergeFirst<T>(tableData: T[] = [], row: T, prop: string, objectEquals: ObjectEqualsFun = defaultObjectEquals) {
    let findRow
    let findRowspan
    let findIndex1
    if (row[prop + '-span']) {
      const {colspan, rowspan} = row[prop + '-span']
      if (rowspan > 0) {
        findRow = row
        findRowspan = rowspan
        findIndex1 = tableData.findIndex(item => objectEquals(item, row))
      }
    }
    if (!findRow) {
      // 就是第一个的下标
      const findIndex = tableData.findIndex(item => objectEquals(item, row))
      if (findIndex > -1) {
        const item = tableData[findIndex]
        if (item[prop + '-span']) {
          const {colspan, rowspan} = item[prop + '-span']
          if (rowspan > 0) {
            findRow = item
            findRowspan = rowspan
            findIndex1 = findIndex
          }
        }
      }
    }
    return {findRow, findIndex: findIndex1, findRowspan}
  }

  static selectAllClickWidhRowMerge<T>(tableData: T[] = [], selectRows: T[]) {
    if (selectRows.length > 0) {
      tableData.forEach(i => {
        i[otherField.select] = true
      })
    } else {
      tableData.forEach(i => {
        i[otherField.select] = false
      })
    }
    return [...selectRows]
  }

  /**
   * 为了避免死循环，使用行点击事件进行触发
   <DynamicTable
   @row-click="handleRowClick"
   @select="tableSelectClick"
   @select-all="tableSelectAllClick"
   >
   </DynamicTable>
   tableSelectClick(selection, row) {
      this.tableSelect = elTableUtils.selectionChangeWithRowMerge(this.mergeTable, this.tableSelect, row, 'index1', this.$refs.DynamicTableRef)
    },
   tableSelectAllClick(selection) {
      this.tableSelect = elTableUtils.selectAllClickWidhRowMerge(this.mergeTable, selection)
    },
   handleRowClick(row, column, event) {
      this.tableSelect = elTableUtils.selectionChangeWithRowMerge(this.mergeTable, this.tableSelect, row, 'index1', this.$refs.DynamicTableRef)
    }
   * @param tableData
   * @param oldSelectRows
   * @param row 点击的row
   * @param prop 关联列的prop
   * @param dyTableVm 动态对表格的实例
   * @param objectEquals 判断两个对象相等
   * @param tableSelectChange 是否控制表格切换选中，默认为true，如果是放在selectObject中使用一定要false
   * @returns {*[]}
   */
  static selectionChangeWithRowMerge<T extends object>(tableData: T[] = [],
                                                       oldSelectRows: T[] = [],
                                                       row: T,
                                                       prop: string = '',
                                                       dyTableVm: DynamicTable,
                                                       objectEquals: ObjectEqualsFun = defaultObjectEquals,
                                                       tableSelectChange: boolean = true
  ): T[] {
    if (!dyTableVm) {
      throw new Error('动态表格不能为空')
    }
    oldSelectRows = deepClone(oldSelectRows)
    let result: T[] = []
    if (dyTableVm.selectMultiple) {
      const elTableRef = dyTableVm.$refs.elTableRef
      // 判断选中的rows是否有row
      const findIndex = oldSelectRows.findIndex(oldRow => objectEquals(oldRow, row))
      if (findIndex > -1) { // 删除
        const {findIndex, findRowspan} = elTableUtils.findRowMergeFirst(tableData, row, prop, objectEquals)
        for (let i = findIndex; i < findIndex + findRowspan; i++) {
          oldSelectRows.splice(oldSelectRows.findIndex(del => objectEquals(del, tableData[i])), 1)
          if (tableSelectChange) {
            elTableRef.toggleRowSelection(tableData[i], false)
          }
        }
      } else {
        oldSelectRows.push(row)
      }
      let oldFindRow
      oldSelectRows.forEach(row => {
        const {findIndex, findRowspan, findRow} = elTableUtils.findRowMergeFirst(tableData, row, prop, objectEquals)
        if (!oldFindRow || !objectEquals(oldFindRow, findRow)) {
          oldFindRow = findRow
          for (let i = findIndex; i < findIndex + findRowspan; i++) {
            result.push(tableData[i])
            if (tableSelectChange) {
              elTableRef.toggleRowSelection(tableData[i], true)
            }
          }
        }
      })
      result = result.sort((a, b) => {
        const a1 = tableData.findIndex(item => objectEquals(item, a))
        const b1 = tableData.findIndex(item => objectEquals(item, b))
        return a1 - b1
      })
    } else {
      const {findIndex, findRowspan} = elTableUtils.findRowMergeFirst(tableData, row, prop, objectEquals)
      if (dyTableVm[otherField.zhixinRadio] === findIndex) {
        dyTableVm.zhixinRadio = undefined
        dyTableVm[otherField.zhixinRadio] = undefined
      } else {
        dyTableVm[otherField.zhixinRadio] = findIndex
        dyTableVm.$nextTick(() => {
          dyTableVm.$set(dyTableVm, 'zhixinRadio', findIndex)
        })
        for (let i = findIndex; i < findRowspan + findIndex; i++) {
          result.push(tableData[i])
        }
      }
    }
    return result
  }

  /**
   * 查找合并的行数据，可以用来处理合并行样式
   * 在cellClassName方法中添加一个挂空的监听变量，控制这个变量用于渲染class
   *   cellClassName:({ row, rowIndex })=>{
   *           this.renderClass // 这个在data中定义一下，鼠标进出都修改这个值，触发渲染
   * @param tableData
   * @param row
   * @param prop
   * @param objectEquals
   * @returns {*[]}
   */
  static findMergeRowsWithProp<T>(tableData: T[], row: T, prop: string, objectEquals: ObjectEqualsFun = defaultObjectEquals) {
    const {findIndex, findRowspan} = elTableUtils.findRowMergeFirst(tableData, row, prop, objectEquals)
    const result: T[] = []
    for (let i = findIndex; i < findIndex + findRowspan; i++) {
      result.push(tableData[i])
    }
    return result
  }

  /**
   * 放在合并方法里面
   *   const result=elTableUtils.mergeSelectWithOtherProp(row,column,this.selectConfig.prop,'genProp0')
   *         if(result){
   *           return result
   *         }
   * @param row
   * @param column
   * @param selectProp select自己的prop
   * @param otherProp 关联列的prop
   * @returns {*}
   */
  static mergeSelectWithOtherProp<T>(row: T, column: TableColumn, selectProp: string, otherProp: string) {
    if (column.property === selectProp) {
      const span = otherProp + '-span'
      if (row[span]) {
        return row[span]
      }
    }
  }

  // 表头合并用的不多，且没有方法
  /**
   * 这里给个列子
   headerStyle({ row, column, rowIndex, columnIndex }) {
      if (rowIndex === this.headerMergeRow) {
        if (columnIndex === 0) {
          this.$nextTick(() => {
            if (this.tableParentEl?.getElementsByClassName(column.id).length !== 0) {
              this.tableParentEl
                ?.getElementsByClassName(column.id)[0]
                .setAttribute('colSpan', '2')
            }
          })
        }
        if (columnIndex === 1) {
          return 'display: none'
        }
      }
    },
   */


  /**
   * 返回一个移除联动的函数
   * @param dyTables
   */
  // @ts-ignore
  static multipleTableScrollX(dyTables: DynamicTable[]) {
    const doms = dyTables.map(i => {
      // @ts-ignore
      return i.$refs.elTableRef.bodyWrapper as HTMLElement
    })
    const scroll = (item: HTMLElement) => {
      doms.forEach(i => {
        if (i !== item) {
          i.scrollLeft = item.scrollLeft
        }
      })
    }
    const functions: any[] = []
    doms.forEach((i, index) => {
      functions.push(() => scroll(i))
      i.addEventListener('scroll', functions[index])
    })
    return () => {
      doms.forEach((i, index) => {
        i.removeEventListener('scroll', functions[index])
      })
    }
  }
}
